package security;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.SecretKey;

import org.bouncycastle.util.encoders.Base64;

import util.KeyReader;

/**
 * Provides methods for HMAC security.
 * 
 * @author Lukas
 *
 */
public class HMACutil {
	private static Mac hMac = null;
	
	/**
	 * Computes the HMAC of the message.
	 * @param message The message.
	 * @return The hmac.
	 * @throws IOException
	 */
	public static String getHMAC(String message, String user) throws IOException {
		initHmac(user);
		hMac.update(message.getBytes());
		byte[] hash = hMac.doFinal();
		return new String(Base64.encode(hash));
	}
	
	/**
	 * Checks if someone tampered with the message.
	 * @param message The message.
	 * @return <tt>true</tt> if everything is ok.
	 * @throws IOException
	 */
	public static boolean checkHMAC(String message, String user) throws IOException {
		initHmac(user);
		int pos = message.lastIndexOf(' ');
		;
		
		hMac.update(message.substring(0, pos).getBytes());
		byte[] hash = hMac.doFinal();
		byte[] receivedHash = Base64.decode(message.substring(pos+1));
		if (hash.length != receivedHash.length) {
			return false;
		}
		for (int i = 0; i < hash.length; i++) {
			if (hash[i] != receivedHash[i]) {
				return false;
			}
		}
		return true;
	}
	
	private static void initHmac(String user) throws IOException {
		KeyReader kr = KeyReader.getInstance();
		SecretKey secKey = kr.readSecretKey(user);
		try {
			hMac = Mac.getInstance("HmacSHA256");
			hMac.init(secKey);
		} catch (NoSuchAlgorithmException e) {
			throw new IOException(e);
		} catch (InvalidKeyException e) {
			throw new IOException(e);
		}
	}
}
